---@class TBS.SkillNodeBase
local SkillNodeBase = TBS.CreateClass("SkillNodeBase")
function SkillNodeBase:ctor(skill,delay)
    ---@type TBS.Skill
    self.skill = skill        --技能
    self.isExecute = false  --是否已执行
    self.delayTime = delay      --延时执行
    self.curTime = 0        --当前时间
    self.isPause = false
    self.isExecuteInHit = false
    self.audio = nil    --音效
    self:OnCreate()
end
function SkillNodeBase:OnCreate()
end
function SkillNodeBase:OnDestroy()
end
function SkillNodeBase:ExecuteForAfterDamage()
    self.isExecuteInHit = true
end
function SkillNodeBase:Reset()
    self.isExecute = false
    self.curTime = 0
    if self.isExecuteInHit then
        self.isPause = true
        self.skill:RegisterCallback(TBS.Config.SkillCallbackType.hitAfter,self,self.HitExecute)
    end
end
function SkillNodeBase:SetAudio(audio)
    self.audio = audio
end
---@param hitContext HitContext
function SkillNodeBase:HitExecute(hitContext)

end
function SkillNodeBase:Pause(isPause)
    self.isPause = isPause
end
function SkillNodeBase:Update(dt)
    if not self.skill then return end
    if self.isExecute then return end
    if self.isPause then return end
    self.curTime = self.curTime + dt
    if self.curTime < self.delayTime then
        return
    end
    self:Execute()
end
function SkillNodeBase:Execute()
    if self.isExecute then return end
    self.isExecute = true
    AudioManager.Play(self.audio)
    self:DoExecute()
end
function SkillNodeBase:DoExecute()

end
---@class TBS.EffectNode:TBS.SkillNodeBase
---@field New fun(skill,delay):TBS.EffectNode
local EffectNode = TBS.CreateClass("EffectNode","SkillNodeBase")
function EffectNode:OnCreate()
    self.resName = nil      --特效路径
    self.resAction = nil    --特效动作
    self.offX = 0           --偏移量
    self.offY = 0           --偏移量
    self.targetType = 0
    self.PosType = TBS.Config.EffectPosType.caster --目标类型 1施法者 2目标
    self.resDuring = 0.2      --持续时间
    self.isBullet = false
    self.audio = nil        --音效
    self.damage = 0
    self.randomRes = nil
    self.delayDestroyTime = 0
    self.animationEvent = nil
    self.scale = 1
    self.hasRandomRotate = false
    self.randomRotateMin = 0
    self.randomRotateMax = 0
    self.hasRandomBorn = false
    self.randomBornMinX = 0
    self.randomBornMinY = 0
    self.randomBornMaxX = 0
    self.randomBornMaxY = 0
    self.hasRandomTargetPos = false
    self.randomTargetMinX = 0
    self.randomTargetMinY = 0
    self.randomTargetMaxX = 0
    self.randomTargetMaxY = 0
    self.isUltimateEffect = false
    self.drawingName = ""
    self.drawingType = 0
    self.isProduceByTeamAllHeroAndFollow = false
    self.effectLoadDoneCallback = nil
    self.effectLoadDoneCallbackTB = nil
end

function EffectNode:Set(resName,resAction,during,audio)
    self.resName = resName
    self.resAction = resAction
    self.resDuring = during
    self.audio = audio
end
function EffectNode:SetOffset(offX,offY,posType)
    self.offX = offX or 0
    self.offY = offY or 0
    self.PosType = posType
end
function EffectNode:SetRandomTargetPos(minX,minY,maxX,maxY)
    self.hasRandomTargetPos = true
    self.randomTargetMinX = minX
    self.randomTargetMinY = minY
    self.randomTargetMaxX = maxX
    self.randomTargetMaxY = maxY
end
function EffectNode:SetUltimateDrawing(drawingName,drawingType)
    self.isUltimateEffect = true
    self.drawingName = drawingName
    self.drawingType = drawingType
end
function EffectNode:SetEffectLoadDoneCallback(callback ,tb)
    self.effectLoadDoneCallback = callback
    self.effectLoadDoneCallbackTB = tb
end
function EffectNode:SetProduceByTeamAllHeroAndFollow(enable)
    self.isProduceByTeamAllHeroAndFollow = enable
end
function EffectNode:SetScale(scale)
    self.scale = scale
end
function EffectNode:HasRandomRes()
    return self.randomRes ~= nil and #self.randomRes > 0
end
function EffectNode:SetRandomRes(resList)
    if not resList then return end
    self.randomRes = {}
    for k,v in pairs(resList) do
        table.insert(self.randomRes,"Prefabs/Skill/"..v)
    end
end
function EffectNode:SetRandomRotate(min,max)
    self.hasRandomRotate = true
    self.randomRotateMin = min
    self.randomRotateMax = max
end
function EffectNode:SetRandomBornPos(minX,minY,maxX,maxY)
    self.hasRandomBorn = true
    self.randomBornMinX = minX
    self.randomBornMinY = minY
    self.randomBornMaxX = maxX
    self.randomBornMaxY = maxY
end
function EffectNode:SetAnimEvent(animationEvent)
    self.animationEvent = animationEvent
end
function EffectNode:SetDelayDestroyTime(time)
    self.delayDestroyTime = time
end
function EffectNode:SetBullet(isBullet,damage,targetType)
    self.isBullet = isBullet
    self.damage = damage or 0
    self.targetType = targetType
end
function EffectNode:HitExecute(hitContext)
    self.offX = hitContext.posX
    self.offY = hitContext.posY
    self.isExecute = false
    self:Execute()
end
function EffectNode:DoExecute()
    if self.skill:GetCaster():IsPlayer() and self.isBullet then
        self:SetRandomTargetPos(-0.5,-0.5,0.5,0)
    end
    if self.isProduceByTeamAllHeroAndFollow then
        local caster = self.skill:GetCaster()
        if caster:IsLeader() then
            local players = TBS.ActorMgr.GetGroupActors(caster:GetGroupId())
            for k,v in pairs(players) do
                TBS.EffectMgr.CreateEffect(self.skill.casterId,v:GetId(),self.skill.uniqueId,self)
            end
        end
        return
    end
    if self.PosType == TBS.Config.EffectPosType.target then
        local targetList = self.skill.targetList
        for k,v in pairs(targetList) do
            TBS.EffectMgr.CreateEffect(self.skill.casterId,v:GetId(),self.skill.uniqueId,self)
        end
    else
        if self.isBullet and self.targetType == TBS.Config.TargetType.target then
            local targetList = self.skill.targetList
            for k,v in pairs(targetList) do
                TBS.EffectMgr.CreateEffect(self.skill.casterId,v:GetId(),self.skill.uniqueId,self)
            end
        else
            TBS.EffectMgr.CreateEffect(self.skill.casterId,0,self.skill.uniqueId,self)
        end
    end
end

---@class TBS.BuffNode:TBS.SkillNodeBase
---@field New fun(skill,delay):TBS.BuffNode
local BuffNode = TBS.CreateClass("BuffNode","SkillNodeBase")
function BuffNode:OnCreate()
    self.buffId = 0
    self.targetType = 0
end
function BuffNode:Set(buffId,targetType)
    self.buffId = buffId
    self.targetType = targetType
end
---@param hitContext HitContext
function BuffNode:HitExecute(hitContext)
    self:Execute()
end
function BuffNode:DoExecute()
    --self.skill:CheckAddBuff(self.buffId)
    --[[if self.targetType == TBS.Config.TargetType.target then
        local targetList = self.skill.targetList
        for k,v in pairs(targetList) do
            v:AddBuff(self.buffId)
        end
    else
        local actor = TBS.ActorMgr.GetActor(self.skill.casterId)
        if actor then
            actor:AddBuff(self.buffId)
        end
    end]]
end
---@class TBS.ShakeNode:TBS.SkillNodeBase
---@field New fun(skill,delay):TBS.ShakeNode
local ShakeNode = TBS.CreateClass("ShakeNode","SkillNodeBase")
function ShakeNode:OnCreate()

end
---@param hitContext HitContext
function ShakeNode:HitExecute(hitContext)
    self:Execute()
end
function ShakeNode:DoExecute()
    local name = dataTable.getDataTableByStringId("t_collocationskillshow", self.skill.skillId,"f_ShockType")
    FireEvent(TBS.Config.Event.ScreenShake,name)
end
---@class TBS.AnimationEventNode:TBS.SkillNodeBase
---@field New fun(skill,delay):TBS.AnimationEventNode
local AnimationEventNode = TBS.CreateClass("AnimationEventNode","SkillNodeBase")
function AnimationEventNode:OnCreate()
    self.isUseFrameEvent = false
end
---@param effectNode TBS.EffectNode
function AnimationEventNode:Set(isUseEvent,effectNode)
    self.isUseFrameEvent = isUseEvent
    if self.isUseFrameEvent then
        self.isPause = true
        local function animEvent(event,data)
            if event and event.Data.Name == "hit01" then
                self:Execute()
                self.skill:DoSkillCallback(TBS.Config.SkillCallbackType.attackFrameEventCallback)
            end
        end
        effectNode:SetAnimEvent(animEvent)
    end
end
function AnimationEventNode:DoExecute()
    local _list = self.skill.targetList
    if table.getn(_list) == 0 then
        self.skill:HitEmpty()
        return
    end
    for k,v in pairs(_list) do
        local p = v:GetPos()
        self.skill:Hit(v,p.x,p.y)
    end
end


